package com.gitee.cnlongdb.basic.utils;

import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitee.cnlongdb.basic.entity.query.LongDbSort;
import com.gitee.cnlongdb.basic.enums.sort.LongDbSortMode;
import com.gitee.cnlongdb.basic.enums.sort.LongDbSortTypes;
	
/**
 * 系统名称：MySortList.java
 * 模块名称：
 * 模块描述：这是一个自定义排序的类，专门针对列表（List）中的数据进行排序；可按指定方法进行。
 * 			目前实现对字符串（String）、日期（Date）、整型（Integer）等三种对象进行排序。
 * 功能列表：
 * 模块作者：ZOUYONG
 * 开发时间：2018年12月5日 下午9:51:54
 * 模块路径：com.gitee.cnlongdb.basic.utils.MySortList
 * 更新记录：
 */
public class MySortList<E> {

	private static final Logger logger = (Logger) LoggerFactory.getLogger(MySortList.class);

	/**
	 * 功能描述：根据字符串指定规则多属性排序
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年11月30日 下午4:37:52
	 × 返回数据：void
	 */
	public static List<String> sortString(List<String> list, final List<LongDbSort> sortList) {
		Collections.sort(list, new Comparator<String>() {
			public int compare(String arg1, String arg2) {
				int result = 0;
				for (int i = 0; i < sortList.size(); i++) {
					LongDbSort sort = sortList.get(i);
					try {
						boolean isAsc = sort.getOrder().equals(LongDbSortMode.ASC.name());
						Object obj1 = ListSortUtils.forceGetFieldString(arg1, sort.getField());
						Object obj2 = ListSortUtils.forceGetFieldString(arg2, sort.getField());
						result = execSortOperator(obj1, obj2, isAsc, sort.getType());
						if (0 != result) {
							break;
						}
					} catch (Exception e) {
						logger.error("数据排序异常：{}", e.getMessage());
					}
				}
				return result;
			}
		});
		return list;
	}
	
	/**
	 * 功能描述：分类型进行排序
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年12月21日 下午4:33:02
	 × 返回数据：int
	 */
	private static int execSortOperator(Object obj1, Object obj2, boolean isAsc, String sortType) throws Exception {
		int result = 0;

		// 空值或NULL值放在最后
		if(null == obj1 || StringUtils.isBlank(obj1.toString())) {
			obj1 = ListSortUtils.setObjectValue(sortType, obj1, isAsc);
		}
		if(null == obj2 || StringUtils.isBlank(obj2.toString())) {
			obj2 = ListSortUtils.setObjectValue(sortType, obj2, isAsc);
		}
		
		// 字符串
		if (sortType.equals(LongDbSortTypes.String.name())) {
			result = obj1.toString().compareTo(obj2.toString());
		}
		// 日期
		else if (sortType.equals(LongDbSortTypes.Date.name())) {
			long time = 0;
			if(obj1 instanceof Date) {
				time = ((Date) obj1).getTime() - ((Date) obj2).getTime();
			} else {
				time = new Date(Long.valueOf(obj1.toString())).getTime() - new Date(Long.valueOf(obj2.toString())).getTime();
			}
			if (time > 0) {
				result = 1;
			} else if (time < 0) {
				result = -1;
			} else {
				result = 0;
			}
		}
		// 数字类型
		else if (sortType.equals(LongDbSortTypes.Number.name())) {
			// 整型（Method的返回参数可以是int的，因为JDK1.5之后，Integer与int可以自动转换了）
			if(null == obj1) { obj1 = "0"; }
			if(null == obj2) { obj2 = "0"; }
			result = (int) (Float.valueOf(obj1.toString()) - Float.valueOf(obj2.toString()));
		}
		// 目前尚不支持的对象，直接转换为String，然后比较，后果未知
		else {
			result = obj1.toString().compareTo(obj2.toString());
		}
		if (!isAsc) {
			// 倒序
			result = -result;
		}
		return result;
	}
	/**
	 * 功能描述：根据对象多属性排序
	 × 模块作者：ZOUYONG
	 × 开发时间：2018年11月30日 下午4:37:52
	 × 返回数据：void
	 */
	public void sortObject(List<E> list, final List<LongDbSort> sortList) {
		Collections.sort(list, new Comparator<Object>() {
			public int compare(Object arg1, Object arg2) {
				int result = 0;
				for (int i = 0; i < sortList.size(); i++) {
					LongDbSort sort = sortList.get(i);
					try {
						boolean isAsc = sort.getOrder().equals(LongDbSortMode.ASC.name());
						Object obj1 = ListSortUtils.forceGetFieldValue(arg1, sort.getField());
						Object obj2 = ListSortUtils.forceGetFieldValue(arg2, sort.getField());
						result = execSortOperator(obj1, obj2, isAsc, sort.getType());
						if (0 != result) {
							break;
						}
					} catch (Exception e) {
						logger.error("数据排序异常：{}", e.getMessage());
					}
				}
				return result;
			}
		});
	}

}
